{
    open Parser
	exception LexError
}

let id     = ['a'-'z' 'A'-'Z' '_' '$'] ['a'-'z' 'A'-'Z' '0'-'9' '_' '$']*
let num    = ['0'-'9']+ ( "." ['0'-'9']* )?
let sp     = [ '\n' ' ' '\t' ]+
let sp_opt = [ '\n' ' ' '\t' ]*

rule token = parse
  | "\n"                             { Lexing.new_line lexbuf; token lexbuf }
  | [' ' '\t']+                      { token lexbuf }
  | "<" (id as x)                    { LT_ID x }
  | "</" (id as x) ">"               { LT_SLASH_ID_GT x }
  | (id as x) sp_opt '=' sp_opt      { ID_SP_EQ_SP x }
  | "/>"                             { SLASH_GT }
  | '>'                              { GT }
  | "<!--"                           { comment "" lexbuf }
  | "\""                             { dqstring "" lexbuf }
  | "\'"                             { qstring "" lexbuf }
  | eof                              { EOF }
  | (['\208' '\209'] _) as x         { word x lexbuf }
  | [^ ' ' '\n' '\t' '>' '<'] as x   { word (Char.escaped x) lexbuf }

and word buf = parse
  | [^ ' ' '\n' '\t' '>' '<']* as x  { WORD (buf ^ x) }

and dqstring buf = parse
  | "\""                             { STRING buf }
  | (['\208' '\209'] _) as x         { dqstring (buf ^ x) lexbuf }
  | _ as x                           { dqstring (buf ^ (Char.escaped x)) lexbuf }

and qstring buf = parse
  | "\'"                             { STRING buf }
  | (['\208' '\209'] _) as x         { qstring (buf ^ x) lexbuf }
  | _ as x                           { qstring (buf ^ (Char.escaped x)) lexbuf }

and comment buf = parse
  | "-->"                            { COMMENT buf }
  | (['\208' '\209'] _) as x         { comment (buf ^ x) lexbuf }
  | _ as x                           { comment (buf ^ (Char.escaped x)) lexbuf }





